﻿using System;
using System.Linq;
using GatewayBizProcess.Db;

namespace GatewayBizProcess.Facade
{
    public static class DataSync
    {
        //todo:同步在线实时数据到总量试点平台，污染源排口号没有写，用缓冲处理下，另只将试点企业数据同步
        public static void Sync2011()
        {
            using (var pGxtCtx = new PlatformGxtContext())
            using (var pZrCtx = new PlatformZrContext())
            {
                var timeEnd = DateTime.Now.AddMinutes(15);
                var maps = pZrCtx.map_mn.Where(t => t.is_enable == true).ToList();
                foreach (var map in maps)
                {
                    var theLastRecord =
                        pGxtCtx.view_pilot_data_real
                            .Where(t => t.datatime < timeEnd)
                            .Where(t => t.MN.Equals(map.online_mn))
                            .OrderByDescending(t => t.datatime)
                            .FirstOrDefault();
                    if (theLastRecord != null)
                    {
                        var theTime = theLastRecord.datatime;
                        var target =
                            pZrCtx.data_realtime_main
                                .Where(t => t.monitor_time == theTime)
                                .FirstOrDefault(t => t.mn.Equals(map.total_pilot_mn));
                        if (target == null)
                        {
                            var port = BaseInfoBuffer.GetInfo(map.total_pilot_mn);
                            var main = new data_realtime_main
                            {
                                mn = map.total_pilot_mn,
                                is_synchronize = false,
                                monitor_time = theTime,
                                pollutant_type_id = port?.pollutant_type_id,
                                ps_base_id = port?.ps_base_id,
                                ps_pi_id = port?.id
                            };
                            pZrCtx.data_realtime_main.Add(main);
                            pZrCtx.SaveChanges();
                            var theSameDataTimeAndMnRecords =
                                pGxtCtx.view_pilot_data_real.Where(t => t.datatime == theTime)
                                    .Where(t => t.MN.Equals(map.online_mn))
                                    .ToList();
                            foreach (var item in theSameDataTimeAndMnRecords)
                            {
                                if (item.rtd != null)
                                {
                                    var detail = new data_realtime
                                    {
                                        pollutant_code = item.pollutant,
                                        flag = "0",
                                        main_id = main.id,
                                        rtd = item.rtd.Value,
                                        zsrtd = item.rtd.Value
                                    };
                                    pZrCtx.data_realtime.Add(detail);
                                }
                            }
                            pZrCtx.SaveChanges();
                        }
                    }
                }
            }

        }
        //todo:同步在线实时数据到总量试点平台，污染源排口号没有写，用缓冲处理下，另只将试点企业数据同步
        public static void Sync2061()
        {
            using (var pZrCtx = new PlatformZrContext())
            {
                var maps = pZrCtx.map_mn.Where(t => t.is_enable == true);
                foreach (var map in maps)
                {
                    SyncHourData(map);
                    //SyncDayData(map);
                    //SyncMonthData(map);
                    //SyncYearData(map);
                    SyncGxtHourDataToZrDayData(map);
                    SyncGxtDayDataToZrMonthData(map);
                    SyncGxtMonthDataToZrYearData(map);
                }
            }
        }
        //private static void SyncYearData(map_mn map)
        //{
        //    using (var pGxtCtx = new PlatformGxtContext())
        //    using (var pZrCtx = new PlatformZrContext())
        //    {
        //        var now = DateTime.Now;
        //        DateTime theYear = new DateTime(now.Year, 1, 1);
        //        DateTime theNextYear = theYear.AddYears(1);
        //        var theLastRecord = pGxtCtx.view_pilot_data_year.Where(t => t.datatime >= theYear)
        //            .Where(t => t.datatime < theNextYear)
        //            .Where(t => t.MN.Equals(map.online_mn))
        //            .OrderByDescending(t => t.datatime)
        //            .FirstOrDefault();
        //        if (theLastRecord?.datatime != null)
        //        {
        //            var theTime = theLastRecord.datatime.Value;
        //            var target = pZrCtx.data_year_main
        //                .Where(t => t.monitor_time == theTime)
        //                .FirstOrDefault(t => t.mn.Equals(map.total_pilot_mn));
        //            if (target == null)
        //            {
        //                var port = BaseInfoBuffer.GetInfo(map.total_pilot_mn);
        //                var main = new data_year_main
        //                {
        //                    mn = map.total_pilot_mn,
        //                    is_synchronize = false,
        //                    monitor_time = theTime,
        //                    pollutant_type_id = port?.pollutant_type_id,
        //                    ps_base_id = port?.ps_base_id,
        //                    ps_pi_id = port?.id
        //                };
        //                pZrCtx.data_year_main.Add(main);
        //                pZrCtx.SaveChanges();
        //                var theSameDataTimeAndMnRecords =
        //                    pGxtCtx.view_pilot_data_year.Where(t => t.datatime == theTime)
        //                        .Where(t => t.MN.Equals(map.online_mn))
        //                        .ToList();
        //                foreach (var item in theSameDataTimeAndMnRecords)
        //                {
        //                    if (item.cou != null)
        //                    {
        //                        var detail = new data_year
        //                        {
        //                            pollutant_code = item.pollutant,
        //                            main_id = main.id,
        //                            Cou = item.cou.Value,
        //                            Min = item.min,
        //                            Max = item.max,
        //                            Avg = item.avg
        //                        };
        //                        pZrCtx.data_year.Add(detail);
        //                    }
        //                }
        //                pZrCtx.SaveChanges();
        //            }
        //        }
        //    }
        //}
        //private static void SyncMonthData(map_mn map)
        //{
        //    using (var pGxtCtx = new PlatformGxtContext())
        //    using (var pZrCtx = new PlatformZrContext())
        //    {
        //        var now = DateTime.Now;
        //        DateTime theMonth = new DateTime(now.Year, now.Month, now.Day);
        //        DateTime theNextMonth = theMonth.AddMonths(1);
        //        var theLastMonth = pGxtCtx.view_pilot_data_month.Where(t => t.datatime >= theMonth)
        //            .Where(t => t.datatime < theNextMonth)
        //            .Where(t => t.MN.Equals(map.online_mn))
        //            .OrderByDescending(t => t.datatime)
        //            .FirstOrDefault();
        //        if (theLastMonth?.datatime != null)
        //        {
        //            var theTime = theLastMonth.datatime.Value;
        //            var target = pZrCtx.data_month_main
        //                .Where(t => t.monitor_time == theTime)
        //                .FirstOrDefault(t => t.mn.Equals(map.total_pilot_mn));
        //            if (target == null)
        //            {
        //                var port = BaseInfoBuffer.GetInfo(map.total_pilot_mn);
        //                var main = new data_month_main
        //                {
        //                    mn = map.total_pilot_mn,
        //                    is_synchronize = false,
        //                    monitor_time = theTime,
        //                    pollutant_type_id = port?.pollutant_type_id,
        //                    ps_base_id = port?.ps_base_id,
        //                    ps_pi_id = port?.id
        //                };
        //                pZrCtx.data_month_main.Add(main);
        //                pZrCtx.SaveChanges();
        //                var theSameDataTimeAndMnRecords =
        //                    pGxtCtx.view_pilot_data_month.Where(t => t.datatime == theTime)
        //                        .Where(t => t.MN.Equals(map.online_mn))
        //                        .ToList();
        //                foreach (var item in theSameDataTimeAndMnRecords)
        //                {
        //                    if (item.cou != null)
        //                    {
        //                        var detail = new data_month
        //                        {
        //                            pollutant_code = item.pollutant,
        //                            main_id = main.id,
        //                            Cou = item.cou.Value,
        //                            Min = item.min,
        //                            Max = item.max,
        //                            Avg = item.avg
        //                        };
        //                        pZrCtx.data_month.Add(detail);
        //                    }
        //                }
        //                pZrCtx.SaveChanges();
        //            }
        //        }
        //    }
        //}
        //private static void SyncDayData(map_mn map)
        //{
        //    using (var pGxtCtx = new PlatformGxtContext())
        //    using (var pZrCtx = new PlatformZrContext())
        //    {
        //        var now = DateTime.Now;
        //        DateTime theDay = new DateTime(now.Year, now.Month, now.Day);
        //        DateTime theNextDay = theDay.AddDays(1);
        //        var theLastDay = pGxtCtx.view_pilot_data_day.Where(t => t.datatime >= theDay)
        //            .Where(t => t.datatime < theNextDay)
        //            .Where(t => t.MN.Equals(map.online_mn))
        //            .OrderByDescending(t => t.datatime)
        //            .FirstOrDefault();
        //        if (theLastDay?.datatime != null)
        //        {
        //            var theTime = theLastDay.datatime.Value;
        //            var target = pZrCtx.data_day_main
        //                .Where(t => t.monitor_time == theTime)
        //                .FirstOrDefault(t => t.mn.Equals(map.total_pilot_mn));
        //            if (target == null)
        //            {
        //                var port = BaseInfoBuffer.GetInfo(map.total_pilot_mn);
        //                var main = new data_day_main
        //                {
        //                    mn = map.total_pilot_mn,
        //                    is_synchronize = false,
        //                    monitor_time = theTime,
        //                    pollutant_type_id = port?.pollutant_type_id,
        //                    ps_base_id = port?.ps_base_id,
        //                    ps_pi_id = port?.id
        //                };
        //                pZrCtx.data_day_main.Add(main);
        //                pZrCtx.SaveChanges();
        //                var theSameDataTimeAndMnRecords =
        //                    pGxtCtx.view_pilot_data_day.Where(t => t.datatime == theTime)
        //                        .Where(t => t.MN.Equals(map.online_mn))
        //                        .ToList();
        //                foreach (var item in theSameDataTimeAndMnRecords)
        //                {
        //                    if (item.cou != null)
        //                    {
        //                        var detail = new data_day
        //                        {
        //                            pollutant_code = item.pollutant,
        //                            main_id = main.id,
        //                            Cou = item.cou.Value,
        //                            Min = item.min,
        //                            Max = item.max,
        //                            Avg = item.avg
        //                        };
        //                        pZrCtx.data_day.Add(detail);
        //                    }
        //                }
        //                pZrCtx.SaveChanges();
        //            }
        //        }
        //    }
        //}
        private static void SyncHourData(map_mn map)
        {
            using (var pGxtCtx = new PlatformGxtContext())
            using (var pZrCtx = new PlatformZrContext())
            {
                pGxtCtx.Database.CommandTimeout = 300;
                var yearEnd = DateTime.Now.AddMinutes(10);
                var theLastHour =
                pGxtCtx.view_pilot_data_hour
                    .Where(t => t.datatime < yearEnd)
                    .Where(t => t.MN.Equals(map.online_mn))
                    .OrderByDescending(t => t.datatime)
                    .FirstOrDefault();
                if (theLastHour != null)
                {
                    var theTime = theLastHour.datatime;

                    var target =
                        pZrCtx.data_hour_main
                            .Where(t => t.monitor_time == theTime)
                            .FirstOrDefault(t => t.mn.Equals(map.total_pilot_mn));
                    if (target == null)
                    {
                        var port = BaseInfoBuffer.GetInfo(map.total_pilot_mn);
                        var main = new data_hour_main
                        {
                            mn = map.total_pilot_mn,
                            is_synchronize = false,
                            monitor_time = theTime,
                            pollutant_type_id = port?.pollutant_type_id,
                            ps_base_id = port?.ps_base_id,
                            ps_pi_id = port?.id
                        };
                        pZrCtx.data_hour_main.Add(main);
                        pZrCtx.SaveChanges();
                        var theSameDataTimeAndMnRecords =
                            pGxtCtx.view_pilot_data_hour.Where(t => t.datatime == theTime)
                                .Where(t => t.MN.Equals(map.online_mn))
                                .ToList();
                        foreach (var item in theSameDataTimeAndMnRecords)
                        {
                            if (item.cou != null)
                            {
                                var detail = new data_hour
                                {
                                    pollutant_code = item.pollutant,
                                    main_id = main.id,
                                    Cou = item.cou.Value,
                                    Min = item.min,
                                    Max = item.max,
                                    Avg = item.avg
                                };
                                pZrCtx.data_hour.Add(detail);
                            }
                        }
                        pZrCtx.SaveChanges();
                    }
                }
            }
        }
        private static void SyncGxtHourDataToZrDayData(map_mn map)
        {

            using (var pGxtCtx = new PlatformGxtContext())
            using (var pZrCtx = new PlatformZrContext())
            {
                pGxtCtx.Database.CommandTimeout = 300;
                var now = DateTime.Now;
                var begin = new DateTime(now.Year, now.Month, now.Day, 0, 0, 0);
                var end = begin.AddDays(1);
                var theLastItem =
                    pGxtCtx.view_pilot_data_hour
                        .Where(t => t.datatime >= begin)
                        .Where(t => t.datatime < end)
                        .Where(t => t.MN.Equals(map.online_mn))
                        .ToList();
                if (theLastItem.Count > 0)
                {
                    var target =
                         pZrCtx.data_day_main
                             .Where(t => t.monitor_time == begin)
                             .FirstOrDefault(t => t.mn.Equals(map.total_pilot_mn));
                    if (target == null)
                    {
                        var port = BaseInfoBuffer.GetInfo(map.total_pilot_mn);
                        var main = new data_day_main
                        {
                            mn = map.total_pilot_mn,
                            is_synchronize = false,
                            monitor_time = begin,
                            pollutant_type_id = port?.pollutant_type_id,
                            ps_base_id = port?.ps_base_id,
                            ps_pi_id = port?.id
                        };
                        pZrCtx.data_day_main.Add(main);
                        pZrCtx.SaveChanges();
                        var theSameDataTimeAndMnRecords =
                           theLastItem.Select(t => t.pollutant).Distinct();
                        foreach (var item in theSameDataTimeAndMnRecords)
                        {
                            if (item != null)
                            {
                                var sum = theLastItem.Where(t => t.pollutant.Equals(item)).Sum(t => t.cou);
                                if (sum != null)
                                {
                                    var detail = new data_day
                                    {
                                        pollutant_code = item,
                                        main_id = main.id,
                                        Cou = sum.Value,
                                        Min = theLastItem.Where(t => t.pollutant.Equals(item)).Min(t => t.min),
                                        Max = theLastItem.Where(t => t.pollutant.Equals(item)).Max(t => t.max),
                                        Avg = theLastItem.Where(t => t.pollutant.Equals(item)).Average(t => t.avg),
                                    };
                                    pZrCtx.data_day.Add(detail);
                                }
                            }
                        }
                        pZrCtx.SaveChanges();
                    }
                    else
                    {
                        var theSameDataTimeAndMnRecords =
                          theLastItem.Select(t => t.pollutant).Distinct();
                        foreach (var item in theSameDataTimeAndMnRecords)
                        {
                            if (item != null)
                            {
                                var existDetail =
                                    pZrCtx.data_day
                                        .Where(t => t.main_id == target.id)
                                        .FirstOrDefault(t => t.pollutant_code.Equals(item));
                                if (existDetail != null)
                                {
                                    var sum = theLastItem.Where(t => t.pollutant.Equals(item)).Sum(t => t.cou);
                                    if (sum != null)
                                    {
                                        existDetail.Cou = sum.Value;
                                        existDetail.Min = theLastItem.Where(t => t.pollutant.Equals(item)).Min(t => t.min);
                                        existDetail.Max = theLastItem.Where(t => t.pollutant.Equals(item)).Max(t => t.max);
                                        existDetail.Avg = theLastItem.Where(t => t.pollutant.Equals(item)).Average(t => t.avg);
                                    }
                                }
                            }
                        }
                        pZrCtx.SaveChanges();
                    }
                }
            }
        }
        private static void SyncGxtDayDataToZrMonthData(map_mn map)
        {
            using (var pGxtCtx = new PlatformGxtContext())
            using (var pZrCtx = new PlatformZrContext())
            {
                pGxtCtx.Database.CommandTimeout = 300;
                var now = DateTime.Now;
                var begin = new DateTime(now.Year, now.Month, 1, 0, 0, 0);
                var end = begin.AddMonths(1);
                var theLastItem =
                    pGxtCtx.view_pilot_data_day
                        .Where(t => t.datatime >= begin)
                        .Where(t => t.datatime < end)
                        .Where(t => t.MN.Equals(map.online_mn))
                        .ToList();
                if (theLastItem.Count > 0)
                {
                    var target =
                         pZrCtx.data_month_main
                             .Where(t => t.monitor_time == begin)
                             .FirstOrDefault(t => t.mn.Equals(map.total_pilot_mn));
                    if (target == null)
                    {
                        var port = BaseInfoBuffer.GetInfo(map.total_pilot_mn);
                        var main = new data_month_main
                        {
                            mn = map.total_pilot_mn,
                            is_synchronize = false,
                            monitor_time = begin,
                            pollutant_type_id = port?.pollutant_type_id,
                            ps_base_id = port?.ps_base_id,
                            ps_pi_id = port?.id
                        };
                        pZrCtx.data_month_main.Add(main);
                        pZrCtx.SaveChanges();
                        var theSameDataTimeAndMnRecords =
                           theLastItem.Select(t => t.pollutant).Distinct();
                        foreach (var item in theSameDataTimeAndMnRecords)
                        {
                            if (item != null)
                            {
                                var sum = theLastItem.Where(t => t.pollutant.Equals(item)).Sum(t => t.cou);
                                if (sum != null)
                                {
                                    var detail = new data_month
                                    {
                                        pollutant_code = item,
                                        main_id = main.id,
                                        Cou = sum.Value,
                                        Min = theLastItem.Where(t => t.pollutant.Equals(item)).Min(t => t.min),
                                        Max = theLastItem.Where(t => t.pollutant.Equals(item)).Max(t => t.max),
                                        Avg = theLastItem.Where(t => t.pollutant.Equals(item)).Average(t => t.avg),
                                    };
                                    pZrCtx.data_month.Add(detail);
                                }
                            }
                        }
                        pZrCtx.SaveChanges();
                    }
                    else
                    {
                        var theSameDataTimeAndMnRecords =
                          theLastItem.Select(t => t.pollutant).Distinct();
                        foreach (var item in theSameDataTimeAndMnRecords)
                        {
                            if (item != null)
                            {
                                var existDetail =
                                    pZrCtx.data_month
                                        .Where(t => t.main_id == target.id)
                                        .FirstOrDefault(t => t.pollutant_code.Equals(item));
                                if (existDetail != null)
                                {
                                    var sum = theLastItem.Where(t => t.pollutant.Equals(item)).Sum(t => t.cou);
                                    if (sum != null)
                                    {
                                        existDetail.Cou = sum.Value;
                                        existDetail.Min = theLastItem.Where(t => t.pollutant.Equals(item)).Min(t => t.min);
                                        existDetail.Max = theLastItem.Where(t => t.pollutant.Equals(item)).Max(t => t.max);
                                        existDetail.Avg = theLastItem.Where(t => t.pollutant.Equals(item)).Average(t => t.avg);
                                    }
                                }
                            }
                        }
                        pZrCtx.SaveChanges();
                    }
                }
            }
        }
        private static void SyncGxtMonthDataToZrYearData(map_mn map)
        {
            using (var pGxtCtx = new PlatformGxtContext())
            using (var pZrCtx = new PlatformZrContext())
            {
                pGxtCtx.Database.CommandTimeout = 300;
                var now = DateTime.Now;
                var begin = new DateTime(now.Year, 1, 1, 0, 0, 0);
                var end = begin.AddYears(1);
                var theLastItem =
                    pGxtCtx.view_pilot_data_month
                        .Where(t => t.datatime >= begin)
                        .Where(t => t.datatime < end)
                        .Where(t => t.MN.Equals(map.online_mn))
                        .ToList();
                if (theLastItem.Count > 0)
                {
                    var target =
                         pZrCtx.data_year_main
                             .Where(t => t.monitor_time == begin)
                             .FirstOrDefault(t => t.mn.Equals(map.total_pilot_mn));
                    if (target == null)
                    {
                        var port = BaseInfoBuffer.GetInfo(map.total_pilot_mn);
                        var main = new data_year_main
                        {
                            mn = map.total_pilot_mn,
                            is_synchronize = false,
                            monitor_time = begin,
                            pollutant_type_id = port?.pollutant_type_id,
                            ps_base_id = port?.ps_base_id,
                            ps_pi_id = port?.id
                        };
                        pZrCtx.data_year_main.Add(main);
                        pZrCtx.SaveChanges();
                        var theSameDataTimeAndMnRecords =
                           theLastItem.Select(t => t.pollutant).Distinct();
                        foreach (var item in theSameDataTimeAndMnRecords)
                        {
                            if (item != null)
                            {
                                var sum = theLastItem.Where(t => t.pollutant.Equals(item)).Sum(t => t.cou);
                                if (sum != null)
                                {
                                    var detail = new data_year
                                    {
                                        pollutant_code = item,
                                        main_id = main.id,
                                        Cou = sum.Value,
                                        Min = theLastItem.Where(t => t.pollutant.Equals(item)).Min(t => t.min),
                                        Max = theLastItem.Where(t => t.pollutant.Equals(item)).Max(t => t.max),
                                        Avg = theLastItem.Where(t => t.pollutant.Equals(item)).Average(t => t.avg),
                                    };
                                    pZrCtx.data_year.Add(detail);
                                }
                            }
                        }
                        pZrCtx.SaveChanges();
                    }
                    else
                    {
                        var theSameDataTimeAndMnRecords =
                          theLastItem.Select(t => t.pollutant).Distinct();
                        foreach (var item in theSameDataTimeAndMnRecords)
                        {
                            if (item != null)
                            {
                                var existDetail =
                                    pZrCtx.data_year
                                        .Where(t => t.main_id == target.id)
                                        .FirstOrDefault(t => t.pollutant_code.Equals(item));
                                if (existDetail != null)
                                {
                                    var sum = theLastItem.Where(t => t.pollutant.Equals(item)).Sum(t => t.cou);
                                    if (sum != null)
                                    {
                                        existDetail.Cou = sum.Value;
                                        existDetail.Min = theLastItem.Where(t => t.pollutant.Equals(item)).Min(t => t.min);
                                        existDetail.Max = theLastItem.Where(t => t.pollutant.Equals(item)).Max(t => t.max);
                                        existDetail.Avg = theLastItem.Where(t => t.pollutant.Equals(item)).Average(t => t.avg);
                                    }
                                }
                            }
                        }
                        pZrCtx.SaveChanges();
                    }
                }
            }
        }
    }
}
